package com.chapter20.demo6;


import java.util.ArrayList;
import java.util.concurrent.*;

/**
 *
 * 悲观锁：
 * ReadWriteLock维护一对关联锁：一个用于只读操作，一个用于写入。只要没有写入操作，读锁就可以由多个读取线程同时保持，而写锁是独占的。
 * 当一个线程在写入时，不管是读取线程还是其他写入线程都会等待，等待持有锁的线程写入结束释放锁。
 * 而当一个线程在读取时，其他的读取线程可以持有锁，但写入线程只能等待，等待所有持有锁的读取线程释放锁。
 *
 * ReadWriteLock可以解决同时读多个线程，但只有一个线程能够写
 * 的问题。读取线程获取读锁进行读取，写入线程获取写锁进行写入，当
 * 线程正在读的时候，写入线程是无法获得写锁的，只能等待，等待读取
 * 线程释放读锁后才能获取写锁。这种读锁我们称为悲观锁。
 *
 * ReadWriteLock本身就适用于读取线程多而写入线程少的场景，但
 * 由于悲观读锁的存在，有可能导致写入线程因迟迟无法获得写锁而无法
 * 进行写入操作的问题，影响程序执行的效率。
 */
public class UseReadWriteLock {
    public static void main(String[] args) {
        FileOperation fo = new FileOperation("1.txt");
        ExecutorService exec = Executors.newCachedThreadPool();
        //有返回值用Callable
        Callable<String> readTask = ()->
                Thread.currentThread().getName()+"读取内容：" + fo.read();
        //没有返回值用Runnable
        Runnable writeTask = ()->fo.write(new byte[]{});

        ArrayList<Future<String>> results = new ArrayList<>();

        //分别提交5次读取任务和5次写入任务
        for (int i = 0;i<5;i++){
            results.add(exec.submit(readTask));
            exec.submit(writeTask);
        }
        exec.shutdown();
        //打印读取的文件内容
        for(int i =0 ;i<5;i++){
            Future<String> result = results.get(i);
            try {
                System.out.println(result.get());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }



















    }
}
